package handlers

import (
	"strconv"
	"strings"

	"baseService/internal/application"
	"baseService/internal/application/services"
	"baseService/internal/domain/entities"
	"baseService/internal/domain/repositories"
	"baseService/internal/interfaces/http/requests"
	"baseService/internal/pkg/response"
	"baseService/internal/pkg/validator"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// UserHandler 用户相关 HTTP 处理器
type UserHandler struct {
	ctx     *application.AppContext
	service *services.UserService
}

// NewUserHandler 创建用户处理器
func NewUserHandler(ctx *application.AppContext, service *services.UserService) *UserHandler {
	return &UserHandler{
		ctx:     ctx,
		service: service,
	}
}

// GetUsers 用户列表
func (h *UserHandler) GetUsers(c *gin.Context) {
	query, verrs := validator.ValidateQuery[requests.ListUsersRequest](c)
	if verrs != nil {
		response.ValidationError(c, verrs.Error())
		return
	}

	options := &repositories.QueryOptions{
		Page:     query.Page,
		PageSize: query.PageSize,
		Filters:  map[string]interface{}{},
	}
	options.Normalize(1, 50, 500)

	if query.Status != nil {
		options.Filters["status"] = *query.Status
	}

	if query.Keyword != "" {
		options.Conditions = append(options.Conditions, repositories.QueryCondition{
			Field:    "username",
			Operator: "like",
			Value:    query.Keyword,
		})
	}

	if query.Start != "" && query.End != "" {
		options.Conditions = append(options.Conditions, repositories.QueryCondition{
			Field:    "created_at",
			Operator: "between",
			Value:    query.Start,
			Value2:   query.End,
		})
	}

	users, total, err := h.service.ListUsers(c.Request.Context(), options)
	if err != nil {
		response.Error(c, err)
		return
	}

	response.SuccessWithPagination(c, users, total, options.Page, options.PageSize)
}

// GetUser 获取单个用户
func (h *UserHandler) GetUser(c *gin.Context) {
	idParam := c.Param("id")
	userID, err := strconv.ParseUint(idParam, 10, 64)
	if err != nil {
		response.BadRequest(c, "无效的用户ID")
		return
	}

	user, err := h.service.GetUser(c.Request.Context(), uint(userID))
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			response.NotFound(c, "用户不存在")
			return
		}
		response.Error(c, err)
		return
	}

	response.Success(c, user)
}

// CreateUser 创建用户
func (h *UserHandler) CreateUser(c *gin.Context) {
	req, verrs := validator.ValidateJSON[requests.CreateUserRequest](c)
	if verrs != nil {
		response.ValidationError(c, verrs.Error())
		return
	}

	user := &entities.User{
		Username: req.Username,
		Password: req.Password,
	}
	if req.Status != nil {
		user.Status = *req.Status
	}

	if err := h.service.CreateUser(c.Request.Context(), user); err != nil {
		if strings.Contains(err.Error(), "already exists") {
			response.BusinessError(c, "用户名已存在")
			return
		}
		response.Error(c, err)
		return
	}

	response.Created(c, user)
}

// UpdateUser 更新用户
func (h *UserHandler) UpdateUser(c *gin.Context) {
	idParam := c.Param("id")
	userID, err := strconv.ParseUint(idParam, 10, 64)
	if err != nil {
		response.BadRequest(c, "无效的用户ID")
		return
	}

	req, verrs := validator.ValidateJSON[requests.UpdateUserRequest](c)
	if verrs != nil {
		response.ValidationError(c, verrs.Error())
		return
	}

	if err := h.service.EnsureUserExists(c.Request.Context(), uint(userID)); err != nil {
		if err == gorm.ErrRecordNotFound {
			response.NotFound(c, "用户不存在")
			return
		}
		response.Error(c, err)
		return
	}

	fields := make(map[string]interface{})
	if req.Password != nil {
		fields["password"] = *req.Password
	}
	if req.Status != nil {
		fields["status"] = *req.Status
	}

	if err := h.service.UpdateUser(c.Request.Context(), uint(userID), fields); err != nil {
		response.Error(c, err)
		return
	}

	response.Success(c, gin.H{"id": userID})
}

// DeleteUser 删除用户
func (h *UserHandler) DeleteUser(c *gin.Context) {
	idParam := c.Param("id")
	userID, err := strconv.ParseUint(idParam, 10, 64)
	if err != nil {
		response.BadRequest(c, "无效的用户ID")
		return
	}

	if err := h.service.EnsureUserExists(c.Request.Context(), uint(userID)); err != nil {
		if err == gorm.ErrRecordNotFound {
			response.NotFound(c, "用户不存在")
			return
		}
		response.Error(c, err)
		return
	}

	if err := h.service.DeleteUser(c.Request.Context(), uint(userID)); err != nil {
		response.Error(c, err)
		return
	}

	response.Success(c, gin.H{"id": userID}, "删除成功")
}
